﻿using Apps.Common;
using Apps.Models;
using System.Linq;
using System.Collections.Generic;
using System;
using Apps.Models.PL;
using Apps.BLL.Core;
using Apps.Locale;
using Apps.IBLL.DI;
using Microsoft.Practices.Unity;
using Apps.IDAL.DI;
using Apps.Models.DI;
using System.Linq.Expressions;
using Apps.IBLL.PL;
using System.Transactions;
using System.IO;
using LinqToExcel;
using System.Text;
using Apps.IDAL.PL;

namespace Apps.BLL.PL
{

    
    public partial class PL_HC_DETAILSBLL: IPL_HC_DETAILSBLL
    {

        [Dependency]
        public IPL_HC_DETAILSRepository m_Rep { get; set; }

        public virtual List<PL_HC_DETAILS> GetListByParentId(ref GridPager pager, string queryStr, object parentId)
        {
            using (DBContainer db = new DBContainer())
            {
                string parid = parentId.ToString();
                var whereLambda = PredicateBuilder.True<PL_HC_DETAILS>();
                if (!string.IsNullOrWhiteSpace(queryStr))
                {
                    /*whereLambda = whereLambda.And(a => (
                                        a.TRANSPORT_ID.Contains(queryStr)
                                       || a.SUPPLIER_ID.Contains(queryStr)
                                       || a.REMARKS.Contains(queryStr)
                                       || a.PLAN_ID.Contains(queryStr)
                                       || a.MINE_ID.Contains(queryStr)
                                       || a.MATERIEL_ID.Contains(queryStr)
                                       || a.END_TIME.Contains(queryStr)
                                       || a.DETAIL_ID.Contains(queryStr)
                                       || a.CONTRACT_DETAIL_ID.Contains(queryStr)
                                       || a.BEGIN_TIME.Contains(queryStr)
                                       || a.BATCH_CODE.Contains(queryStr)
                    ));
                    */
                }

                if (!string.IsNullOrEmpty(parid))
                {
                    whereLambda = whereLambda.And(p => p.PLAN_ID == parid);
                }
               

                IQueryable<PL_HC_DETAILS> queryData = db.PL_HC_DETAILS.Where(whereLambda.Compile()).AsQueryable();
                pager.totalRows = queryData.Count();
                //排序
                queryData = LinqHelper.SortingAndPaging(queryData, pager.sort, pager.order, pager.page, pager.rows);
                return CreateModelList(ref queryData); ;
            }
        }



        public virtual decimal GetBathCode(DateTime BathCodeDate)
        {
            string datetime = BathCodeDate.ToString("yyyyMMdd").Substring(2, 6);

            return m_Rep.Context.Database.SqlQuery<Decimal>($"SELECT CASE WHEN COUNT(BATCH_CODE)=0 THEN to_number('{datetime + "01"}') ELSE MAX(BATCH_CODE)+1 END FROM ( SELECT BATCH_CODE FROM V_PL_ALL_DETAILS  UNION SELECT BATCH_CODE FROM  PL_HC_PLANS)  WHERE SUBSTR(BATCH_CODE, 1, 6)= '{datetime}'").FirstOrDefault();
        }
        public virtual List<PL_HC_DETAILS> CreateModelList(ref IQueryable<PL_HC_DETAILS> queryData)
        {
            try
            {
                List<PL_HC_DETAILS> modelList = queryData.ToList() ;
                //(from r in queryData
                //                                 select new PL_HC_DETAILS()
                //                                 {
                //                                     DETAIL_ID = r.DETAIL_ID,
                //                                     PLAN_ID = r.PLAN_ID,
                //                                     TRAIN_TYPE_ID = r.TRAIN_TYPE_ID,
                //                                     CAR_NUM = r.CAR_NUM,
                //                                     B_WEIGHT = r.B_WEIGHT,
                //                                     H_WEIGHT = r.H_WEIGHT
                //                                 }).ToList();
                return modelList;
            }
            catch (Exception)
            {

                throw;
            }
        }

        public virtual List<PL_HC_DETAILS> GetList(ref GridPager pager, string queryStr)
        {

            IQueryable<PL_HC_DETAILS> queryData = null;
            if (!string.IsNullOrWhiteSpace(queryStr))
            {
                //queryData = m_Rep.GetList(
                //                a => a.BEGIN_TIME.Contains(queryStr)
                //                || a.END_TIME.Contains(queryStr)
                //                || a.REMARKS.Contains(queryStr)
                //                );
            }
            else
            {
                queryData = m_Rep.GetList();
            }
            pager.totalRows = queryData.Count();
            //排序
            queryData = LinqHelper.SortingAndPaging(queryData, pager.sort, pager.order, pager.page, pager.rows);
            return CreateModelList(ref queryData);
        }

        public virtual List<PL_HC_DETAILS> GetPagerList(ref GridPager pager, Expression<Func<PL_HC_DETAILS, bool>> whereLambda)
        {
            IQueryable<PL_HC_DETAILS> queryData = m_Rep.GetList(whereLambda);

            pager.totalRows = queryData.Count();
            //排序
            queryData = LinqHelper.SortingAndPaging(queryData, pager.sort, pager.order, pager.page, pager.rows);
            return CreateModelList(ref queryData);
        }

        public virtual List<PL_HC_DETAILS> GetList(Expression<Func<PL_HC_DETAILS, bool>> whereLambda)
        {
            try
            {
            IQueryable<PL_HC_DETAILS> queryData = m_Rep.GetList(whereLambda);

            return queryData.ToList();

            }
            catch (Exception )
            {

                throw;
            }
        }



        public virtual bool Create(ref ValidationErrors errors, PL_HC_DETAILS model)
        {
            try
            {
                PL_HC_DETAILS entity = new PL_HC_DETAILS();
                if (!string.IsNullOrEmpty(model.DETAIL_ID))
                {
                    entity = m_Rep.GetById(model.DETAIL_ID);
                    if (entity != null)
                    {
                        errors.Add(Resource.PrimaryRepeat);
                        return false;
                    }
                }
                string[] cars = model.CAR_NUM.Replace("\r\n", " ").Split(' ').Where(p=>p.Length>0).ToArray();
                if (cars.Length > 0)
                {
                    List<PL_HC_DETAILS> list = new List<PL_HC_DETAILS>();
                    for (int i = 0; i < cars.Length; i++)
                    {
                        if (!string.IsNullOrEmpty(cars[i]))
                        {
                            entity = new PL_HC_DETAILS();
                            entity.DETAIL_ID = ResultHelper.NewId;
                            entity.PLAN_ID = model.PLAN_ID;
                            entity.TRAIN_TYPE_ID = "0";
                            entity.B_WEIGHT = 0;
                            entity.H_WEIGHT = 0;
                            entity.CAR_NUM = cars[i];
                            list.Add(entity);
                        }
                    }
                    if (list.Count() > 1)
                    {
                        //using (TransactionScope transactionScope = new TransactionScope())
                        //{
                            if (m_Rep.Create(list.ToArray()))
                            {
                                //transactionScope.Complete();
                                return true;
                            }
                            else
                            {
                                //Transaction.Current.Rollback();
                                return false;
                            }
                        //}
                    }
                    else
                    {
                        if (m_Rep.Create(list[0]))
                        {
                            return true;
                        }
                        else
                        {
                            errors.Add(Resource.InsertFail);
                            return false;
                        }
                    }
                }
                return false;
            }
            catch (Exception ex)
            {
                errors.Add(ex.Message);
                ExceptionHander.WriteException(ex);
                return false;
            }
        }

        public virtual bool Create(ref ValidationErrors errors, List<PL_HC_DETAILS> model)
        {
            try
            {
                    if (model.Count() > 1)
                    {
                        //using (TransactionScope transactionScope = new TransactionScope())
                        //{
                        if (m_Rep.Create(model.ToArray()))
                        {
                            //transactionScope.Complete();
                            return true;
                        }
                        else
                        {
                            //Transaction.Current.Rollback();
                            return false;
                        }
                        //}
                    }
                    else
                    {
                        if (m_Rep.Create(model[0]))
                        {
                            return true;
                        }
                        else
                        {
                            errors.Add(Resource.InsertFail);
                            return false;
                        }
                    }
                //return false;
            }
            catch (Exception ex)
            {
                errors.Add(ex.Message);
                ExceptionHander.WriteException(ex);
                return false;
            }
        }

        public virtual bool Deletes(ref ValidationErrors errors, Expression<Func<PL_HC_DETAILS, bool>> whereLambda)
        {
            try
            {
                using (DBContainer db = new DBContainer())
                {

                    foreach (var entity in db.PL_HC_DETAILS.Where(whereLambda))
                    {
                        db.Entry(entity).State = System.Data.Entity.EntityState.Deleted;
                    }

                    if (db.SaveChanges() > 0)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }

                }
            }
            catch (Exception ex)
            {
                errors.Add(ex.Message);
                ExceptionHander.WriteException(ex);
                return false;
            }
        }

        public virtual bool Delete(ref ValidationErrors errors, object id)
        {
            try
            {
                if (m_Rep.Delete(p=>p.PLAN_ID==id.ToString()) == 1)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                errors.Add(ex.Message);
                ExceptionHander.WriteException(ex);
                return false;
            }
        }

        public virtual bool Delete(ref ValidationErrors errors, object[] deleteCollection)
        {
            try
            {
                if (deleteCollection != null)
                {
                    using (TransactionScope transactionScope = new TransactionScope())
                    {
                        if (m_Rep.Delete(deleteCollection) == deleteCollection.Length)
                        {
                            transactionScope.Complete();
                            return true;
                        }
                        else
                        {
                            Transaction.Current.Rollback();
                            return false;
                        }
                    }
                }
                return false;
            }
            catch (Exception ex)
            {
                errors.Add(ex.Message);
                ExceptionHander.WriteException(ex);
                return false;
            }
        } 




        public virtual bool Edit(ref ValidationErrors errors, PL_HC_DETAILS model)
        {
            try
            {
                PL_HC_DETAILS entity = m_Rep.GetById(model.DETAIL_ID);
                if (entity == null)
                {
                    errors.Add(Resource.Disable);
                    return false;
                }
                entity.DETAIL_ID = model.DETAIL_ID;
                entity.PLAN_ID = model.PLAN_ID;

                if (m_Rep.Edit(entity))
                {
                    return true;
                }
                else
                {
                    errors.Add(Resource.NoDataChange);
                    return false;
                }

            }
            catch (Exception ex)
            {
                errors.Add(ex.Message);
                ExceptionHander.WriteException(ex);
                return false;
            }
        }



        public virtual PL_HC_DETAILS GetById(object id)
        {
            if (IsExists(id))
            {
                PL_HC_DETAILS entity = m_Rep.GetById(id);
                PL_HC_DETAILS model = new PL_HC_DETAILS();
                model.DETAIL_ID = entity.DETAIL_ID;
                model.PLAN_ID = entity.PLAN_ID;


                return model;
            }
            else
            {
                return null;
            }
        }

        public virtual PL_HC_DETAILS GetItem(Expression<Func<PL_HC_DETAILS, bool>> whereLambda)
        {

            PL_HC_DETAILS entity = m_Rep.GetItem(whereLambda);
            if (entity == null) return null;

            PL_HC_DETAILS model = new PL_HC_DETAILS();
            model.DETAIL_ID = entity.DETAIL_ID;
            model.PLAN_ID = entity.PLAN_ID;


            return model;
        }


        /// <summary>
        /// 校验Excel数据,这个方法一般用于重写校验逻辑
        /// </summary>
        public virtual bool CheckImportData(string fileName, List<PL_HC_DETAILS> list, ref ValidationErrors errors)
        {

            var targetFile = new FileInfo(fileName);

            if (!targetFile.Exists)
            {

                errors.Add("导入的数据文件不存在");
                return false;
            }

            var excelFile = new ExcelQueryFactory(fileName);

            //对应列头
            excelFile.AddMapping<PL_HC_DETAILS>(x => x.DETAIL_ID, "DETAIL_ID");
            excelFile.AddMapping<PL_HC_DETAILS>(x => x.PLAN_ID, "PLAN_ID");

            //SheetName
            var excelContent = excelFile.Worksheet<PL_HC_DETAILS>(0);
            int rowIndex = 1;
            //检查数据正确性
            foreach (var row in excelContent)
            {
                var errorMessage = new StringBuilder();
                var entity = new PL_HC_DETAILS();
                entity.DETAIL_ID = row.DETAIL_ID;
                entity.PLAN_ID = row.PLAN_ID;


                //=============================================================================
                if (errorMessage.Length > 0)
                {
                    errors.Add(string.Format(
                        "第 {0} 列发现错误：{1}{2}",
                        rowIndex,
                        errorMessage,
                        "<br/>"));
                }
                list.Add(entity);
                rowIndex += 1;
            }
            if (errors.Count > 0)
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// 保存数据
        /// </summary>
        public virtual void SaveImportData(IEnumerable<PL_HC_DETAILS> list)
        {
            try
            {
                using (DBContainer db = new DBContainer())
                {
                    foreach (var model in list)
                    {
                        PL_HC_DETAILS entity = new PL_HC_DETAILS();
                        entity.DETAIL_ID = model.DETAIL_ID;
                        entity.PLAN_ID = model.PLAN_ID;
                        db.PL_HC_DETAILS.Add(entity);
                    }
                    db.SaveChanges();
                }
            }
            catch
            {
                throw;
            }
        }


        public virtual bool IsExists(object id)
        {
            return m_Rep.IsExist(id);
        }
        public void Dispose()
        {

        }

    }
}